# -*- coding: utf-8 -*-
# @Time    : 17-11-19 下午5:07
# @Author  : Pei Le
# @Email   : le.pei@easytransfer.cn
# @File    : redis_cache.py
# @Software: PyCharm
"""
redis 通用方法 简单版
"""
import pickle
from aioredis import Redis, ConnectionPool

from common import logger
from common.result.error import RedisErr
from common.result.result_code import RedisCont
from common.result import err_msg


class RedisHelper:
    def __init__(self, host=None, password=None, port=None, timeout=60, **kwargs):
        """
        初始化
        :param host: ip
        :param password: 密码
        :param port: 端口
        :param timeout: 过期时间
        """
        try:
            self.timeout = timeout
            pool = ConnectionPool(host=host, password=password, port=port)
            self.redis = Redis(connection_pool=pool)
        except Exception as e:
            logger.error(f"Redis链接失败：{e}")
            raise RedisErr(RedisCont.ConnectionErr, err_msg.FailErr, message="Redis链接失败")

    async def get(self, key, **kwargs):
        """
        获得缓存key值
        :param key:key
        :return: object 没有为None
        """
        result = await self.redis.get(key)
        return pickle.loads(result) if result is not None else None

    async def set(self, key, value, timeout=None, **kwargs):
        """
        设置缓存 不安全  存在就更新，不存在就设置
        :param key: key
        :param value: 值
        :param timeout: 过期时间
        :return: bool
        """
        timeout = timeout if timeout is not None else self.timeout
        if await self.get(key):
            nx, xx = False, True
        else:
            nx, xx = True, False
        value = pickle.dumps(value)
        result = await self.redis.set(name=key, value=pickle.dumps(value), ex=timeout, nx=nx, xx=xx)
        return result

    async def set_safe(self, key=None, value=None, timeout=None, update=False, **kwargs):
        """
        设置缓存 安全 更新必须将update 设置为True 否则无法更新  添加 update为False
        :param key: key
        :param value: 值
        :param timeout: 过期时间
        :param update: 是否更新
        :return: bool
        """
        timeout = timeout if timeout and timeout > 0 else self.timeout
        nx = not update
        xx = update
        value = pickle.dumps(value)
        return await self.redis.set(name=key, value=value, ex=timeout, nx=nx, xx=xx)

    async def delete(self, key=None):
        """
        删除缓存key
        :param key: key
        :return: bool
        """
        return True if await self.redis.delete(key) == 1 else False

    async def delete_cache(self, key=None):
        """
        删除缓存key
        :param key: key
        :return: bool
        """
        return True if await self.redis.delete(key) == 1 else False

    async def get_timeout(self, key=None):
        """
        获得key过期时间
        :param key:
        :return: 过期或者没有返回0
        """

        timeout = await self.redis.ttl(key)
        return timeout if timeout is not None and timeout > 0 else 0

    def refresh_timeout(self, key=None, timeout=None):
        """
        刷新过期时间
        :param key: key
        :param timeout: 过期时间
        :return: bool
        """
        timeout = timeout if timeout and timeout > 0 else self.timeout
        return self.redis.expire(name=key, time=timeout)


if __name__ == '__main__':
    # 测试示例
    from conf.config import Config
    import asyncio
    cache = RedisHelper(host=Config.redis.host, password=Config.redis.password, port=Config.redis.port)
    loop = asyncio.get_event_loop()
    print(loop.run_until_complete(cache.get("admin:data_subscribe_mark_relation_info_insert_239780_11697240")))

